import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.InvalidParameterException;
import java.util.HashMap;
import java.util.Map;

public class ObjectUtil {
    public static void copyProperties(Object source, Object target, String[] properties) {
        // TODO: Implement this method
        if(properties.length == 0){
            throw new InvalidParameterException();
        }

        if(source.getClass() != target.getClass()){
            Map<String,Object> sourceMap = new HashMap<>();
            Map<String,Object> targetMap = new HashMap<>();
            String[] sourceFieldNames = getFiledName(source);
            String[] targetFieldNames = getFiledName(target);
            //对象source
            for(int j=0 ; j<sourceFieldNames.length ; j++){     //遍历所有属性名字
                String name = sourceFieldNames[j];    //获取属性的名字
                Object value = getFieldValueByName(name,source);
                sourceMap.put(name,value);
            }
            //对象target
            for(int j=0 ; j<targetFieldNames.length ; j++){     //遍历所有属性名字
                String name = targetFieldNames[j];    //获取属性的名字
                Object value = getFieldValueByName(name,source);
                targetMap.put(name,value);
            }
            //遍历target，给source存在同名同类型的属性，就能进行拷贝。
            for (Map.Entry <String, Object> entry : targetMap.entrySet()){
                if(sourceMap.containsKey(entry.getKey()) && sourceMap.get(entry.getKey()).getClass() == entry.getValue().getClass()){
                    try {
                        Class c = source.getClass();
                        Field f = c.getDeclaredField(entry.getKey());
                        f.setAccessible(true);
                        f.set(source, entry.getValue());
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                }
            }
            //遍历properties
            for(String propertie : properties){
                if (sourceMap.containsKey(propertie)){
                    if(!(sourceMap.get(propertie) instanceof String)){
                        throw new RuntimeException();
                    }
                }
                if (targetMap.containsKey(propertie)){
                    if(!(targetMap.get(propertie) instanceof String)){
                        throw new RuntimeException();
                    }
                }
            }
        }

    }

    /**
     * 获取属性名数组
     * */
    private static String[] getFiledName(Object o){
        Field[] fields=o.getClass().getDeclaredFields();
        String[] fieldNames=new String[fields.length];
        for(int i=0;i<fields.length;i++){
            fieldNames[i]=fields[i].getName();
        }
        return fieldNames;
    }

    /**
     * 根据属性名获取属性值
     * */
    private static Object getFieldValueByName(String fieldName, Object o) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = o.getClass().getMethod(getter, new Class[] {});
            Object value = method.invoke(o, new Object[] {});
            return value;
        } catch (Exception e) {

            return null;
        }
    }




}
